<template>
  <el-scrollbar class="menu" :native="false" :noresize="false">
    <div :class="['menuList', [globalStore.layout]]">
      <div
        :class="{ menuItem: true, curTab: curIdx === index }"
        :key="item.id"
        @click="_switchTab(item.id - 1, index)"
        v-for="(item, index) in menuList"
      >
        {{ item.title }}
      </div>
    </div>
  </el-scrollbar>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch } from "vue";
import { HOME_URL, MENU_LIST } from "@/config";
import { useGlobalStore } from "@/stores/modules/global";
import { useMenuStore } from "@/stores/modules/menu";
import { useUserStore } from "@/stores/modules/user";
import { hexToRgb } from "@/utils/color";
import { useRouter, useRoute } from "vue-router";
import { routerMap } from "@/utils/routerData";
import { SwitchTab, SetSubMenuList, MatchMenuIdx, MenuItem, MatchRoute } from "../../interfaces";
import { getShowMenuList } from "@/utils";
const router = useRouter();
const route = useRoute();
const globalStore = useGlobalStore();
const menuStore = useMenuStore();
const userStore = useUserStore();

const curTab = ref(-1);
const curIdx = ref(-1);
const isMatched = ref(false);
let menuList: any = reactive(MENU_LIST);
const primary = computed((): number[] => hexToRgb(globalStore.primary));
const baseCol = computed((): string => `rgba(${primary.value[0]}, ${primary.value[1]}, ${primary.value[2]}, 1)`);
const menuBg = computed((): string => `rgba(${primary.value[0]}, ${primary.value[1]}, ${primary.value[2]}, .1)`);
const subMenuList = computed((): Menu.MenuOptions[] => getShowMenuList(menuStore.subMenuList));
const userMenuList = computed((): string[] => userStore.menuList);

/**
 * 切换tab标签
 */
const _switchTab: SwitchTab = function (index: number, cIndex: number): boolean {
  globalStore.setGlobalState("isCollapse", false);
  if (menuStore.activeMenuIdx === index) {
    return false;
  }
  curTab.value = index;
  curIdx.value = cIndex;
  menuStore.updateActiveRoute(route.path);
  setSubMenuList(curTab.value);
  const nextRoute = menuStore.activeRouteList[curTab.value];
  nextRoute ? router.push(nextRoute) : subMenuList.value && router.push(matchRoute(subMenuList.value[0]));
  menuStore.setMenuIdx(curTab.value);
  return true;
};

/**
 * 设置左侧纵向菜单数据
 */
const setSubMenuList: SetSubMenuList = function (key: number): void {
  if (key < 0) return;
  const subMenuList = JSON.parse(JSON.stringify(routerMap.get(key))) as Menu.MenuOptions[];
  menuStore.setSubMenuList(matchUserMenuList(subMenuList));
};
/**
 * 匹配角色管理配置菜单
 */
const matchUserMenuList = (subMenuList: Menu.MenuOptions[]): Menu.MenuOptions[] => {
  let subMenus: Menu.MenuOptions[] = [];
  subMenuList.forEach((item: Menu.MenuOptions) => {
    if (item.children) {
      item.children = matchUserMenuList(item.children);
    }
    if (item.meta?.parentMenuName) {
      subMenus.push(item);
    }
  });
  subMenuList.forEach((item: Menu.MenuOptions) => {
    userMenuList.value.forEach((val: string) => {
      if (item.children) {
        item.children = matchUserMenuList(item.children);
      }
      if ("" + val === item.name) {
        subMenus.push(item);
      }
    });
  });
  return subMenus;
};
/**
 * 根据路由匹配主菜单
 */
const matchMenuIdx: MatchMenuIdx = function (key: number, values: { [key: string]: any }[]): number {
  let matchVal: number = -1;
  values.some((item: MenuItem): void => {
    if (!isMatched.value) {
      if (item.path === route.path) {
        matchVal = key;
        isMatched.value = true;
        return;
      } else {
        if (item.children && item.children.length > 0) {
          matchVal = matchMenuIdx(key, item.children);
        }
      }
    }
  });
  return matchVal;
};

/**
 * 根据菜单子项匹配路由
 */
const matchRoute: MatchRoute = function (subMenuItem: any): string {
  return subMenuItem.children ? matchRoute(subMenuItem.children[0]) : subMenuItem.path;
};

/**
 * 页面初始化
 */
const initPage: () => void = function (): void {
  if (route.path === HOME_URL) return;
  isMatched.value = false;
  for (const [key, values] of routerMap.entries()) {
    curTab.value = matchMenuIdx(key, values);
    if (isMatched.value) {
      break;
    }
  }
  menuStore.setMenuIdx(curTab.value);
  menuStore.updateActiveRoute(route.path);
  setSubMenuList(curTab.value);

  menuList.some((item: any, index: number) => {
    if (item.id === curTab.value + 1) {
      curIdx.value = index;
      return;
    }
  });
};

onMounted(() => {
  let menus: any[] = [];
  menuList.forEach((item: any) => {
    userMenuList.value.forEach((val: string) => {
      if (val === item.name) {
        menus.push(item);
      }
    });
  });
  menuList = menus;
  initPage();
});

watch(
  () => route.fullPath,
  (newVal, oldVal) => {
    curTab.value = menuStore.activeMenuIdx;
    newVal !== oldVal && initPage();
  }
);
</script>

<style scoped lang="scss">
$base-col: v-bind("baseCol");
$menu-bg: v-bind("menuBg");
.menu {
  box-sizing: border-box;
  width: 100%;
  height: 54px;
  padding-left: 2%;
  .menuList {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    height: 54px;
    .menuItem {
      box-sizing: border-box;
      min-width: 80px;
      height: 50px;
      padding: 0 10px;
      margin: 0 10px;
      line-height: 50px;
      text-align: center;
      cursor: pointer;
      font: {
        size: 15px;
      }
    }
  }
}

/* stylelint-disable-next-line scss/at-mixin-pattern */
@mixin curTab($default) {
  .curTab {
    overflow: hidden;
    border-bottom: 4px solid #3c6aa1;
  }
}
.vertical {
  color: $base-col;
  @include curTab(true);
}
.classic {
  color: $base-col;
  @include curTab(false);
}
</style>
